package org.bird.concurrent.lock;

import java.util.concurrent.locks.ReadWriteLock;

/**
 * 可重入读写锁
 * @author liangjf
 *
 */
public class ReentrantReadWriteLock {

	Object data;
	volatile boolean cacheValid;//缓存是否有效布尔值
	final ReadWriteLock lock = new java.util.concurrent.locks.ReentrantReadWriteLock();
	
	public static void main(String[] args) {
		final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
		
		new Thread(new Runnable() {
			public void run() {
				lock.processCachedData();
			}
		}, "readwritelock_thread");
	}
	
	public void processCachedData() {
		lock.readLock().lock();//1.读锁
		if(!cacheValid) {//2.读操作，如果数据无效（即在读操作之前有线程修改了data）
			lock.readLock().unlock();//3.释放读锁
			lock.writeLock().lock();//4.添加写锁
			try {
				//再次校验缓存有效性，如果无效
				if(!cacheValid) {
					data = new Object();//5.缓存赋值为最新值
					cacheValid = true;//6.设置缓存有效
				}
				lock.readLock().lock();//7.释放写锁前，写锁降级为读锁（已存在写锁情况下获取读锁，写锁降级为读锁）
			} finally {
				lock.writeLock().unlock();//8.释放写锁，保持读锁
			}
		}
		try {
			//9.使用缓存数据data
		} finally {
			lock.readLock().unlock();//10.释放读锁
		}
	}
}
